"""
数据模型定义
Data Models for Puxiansheng Scraper
"""

from dataclasses import dataclass, field, asdict
from datetime import datetime
from typing import Optional, Dict, Any
import re
import json


@dataclass
class PropertyListing:
    """
    商业地产信息数据模型
    Commercial Property Listing Data Model
    """
    # 必需字段 - Required fields
    id: str
    title: str
    city: str
    district: str
    rent_range: str
    area_range: str
    industry: str
    publish_date: str
    detail_url: str
    business_type: str
    
    # 可选字段 - Optional fields
    transfer_fee: str = ""
    contact_info: str = ""  # 暂时为空，需要登录获取
    created_at: datetime = field(default_factory=datetime.now)
    
    def __post_init__(self):
        """数据初始化后的验证和清洗"""
        self.validate()
        self.clean_data()
    
    def validate(self) -> None:
        """
        验证数据完整性和格式
        Validate data integrity and format
        """
        # 验证必需字段不为空
        required_fields = [
            'id', 'title', 'city', 'district', 'rent_range', 
            'area_range', 'industry', 'publish_date', 'detail_url', 'business_type'
        ]
        
        for field_name in required_fields:
            value = getattr(self, field_name)
            if not value or (isinstance(value, str) and not value.strip()):
                raise ValueError(f"Required field '{field_name}' cannot be empty")
        
        # 验证业态类型
        valid_business_types = ['餐饮', '娱乐', '零售', 'catering', 'entertainment', 'retail']
        if self.business_type not in valid_business_types:
            raise ValueError(f"Invalid business_type: {self.business_type}")
        
        # 验证URL格式
        if not self.detail_url.startswith(('http://', 'https://')):
            raise ValueError(f"Invalid detail_url format: {self.detail_url}")
        
        # 验证城市代码
        valid_cities = ['sz', 'gz', 'bj', 'sh', '深圳', '广州', '北京', '上海']
        if self.city not in valid_cities:
            raise ValueError(f"Invalid city: {self.city}")
    
    def clean_data(self) -> None:
        """
        清洗和标准化数据
        Clean and normalize data
        """
        # 清理标题
        self.title = self._clean_text(self.title)
        
        # 清理区域信息
        self.district = self._clean_text(self.district)
        
        # 标准化租金范围格式
        self.rent_range = self._clean_rent_range(self.rent_range)
        
        # 标准化面积范围格式
        self.area_range = self._clean_area_range(self.area_range)
        
        # 清理行业信息
        self.industry = self._clean_text(self.industry)
        
        # 标准化日期格式
        self.publish_date = self._clean_date(self.publish_date)
        
        # 清理转让费信息
        if self.transfer_fee:
            self.transfer_fee = self._clean_text(self.transfer_fee)
    
    def _clean_text(self, text: str) -> str:
        """清理文本，去除多余空白字符"""
        if not text:
            return ""
        return re.sub(r'\s+', ' ', text.strip())
    
    def _clean_rent_range(self, rent_range: str) -> str:
        """清理租金范围数据"""
        if not rent_range:
            return ""
        
        # 移除多余空白和特殊字符
        cleaned = self._clean_text(rent_range)
        
        # 标准化单位
        cleaned = re.sub(r'元/㎡·月|元/平米·月|元/㎡/月|元/平米/月', '元/㎡·月', cleaned)
        
        return cleaned
    
    def _clean_area_range(self, area_range: str) -> str:
        """清理面积范围数据"""
        if not area_range:
            return ""
        
        # 移除多余空白
        cleaned = self._clean_text(area_range)
        
        # 标准化单位
        cleaned = re.sub(r'㎡|平米|平方米', '㎡', cleaned)
        
        return cleaned
    
    def _clean_date(self, date_str: str) -> str:
        """清理和标准化日期格式"""
        if not date_str:
            return ""
        
        # 移除多余空白
        cleaned = self._clean_text(date_str)
        
        # 处理相对日期（如"今天"、"昨天"等）
        if '今天' in cleaned:
            return datetime.now().strftime('%Y-%m-%d')
        elif '昨天' in cleaned:
            yesterday = datetime.now().replace(day=datetime.now().day-1)
            return yesterday.strftime('%Y-%m-%d')
        
        # 尝试解析常见日期格式
        date_patterns = [
            r'(\d{4})-(\d{1,2})-(\d{1,2})',  # 2024-01-01
            r'(\d{4})年(\d{1,2})月(\d{1,2})日',  # 2024年1月1日
            r'(\d{1,2})-(\d{1,2})',  # 01-01 (当年)
            r'(\d{1,2})月(\d{1,2})日',  # 1月1日 (当年)
        ]
        
        for pattern in date_patterns:
            match = re.search(pattern, cleaned)
            if match:
                groups = match.groups()
                if len(groups) == 3:
                    year, month, day = groups
                    return f"{year}-{month.zfill(2)}-{day.zfill(2)}"
                elif len(groups) == 2:
                    month, day = groups
                    current_year = datetime.now().year
                    return f"{current_year}-{month.zfill(2)}-{day.zfill(2)}"
        
        return cleaned
    
    def to_dict(self) -> Dict[str, Any]:
        """
        转换为字典格式
        Convert to dictionary format
        """
        data = asdict(self)
        # 转换datetime为字符串
        if isinstance(data['created_at'], datetime):
            data['created_at'] = data['created_at'].isoformat()
        return data
    
    def to_json(self, indent: Optional[int] = None) -> str:
        """
        序列化为JSON字符串
        Serialize to JSON string
        """
        return json.dumps(self.to_dict(), ensure_ascii=False, indent=indent)
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'PropertyListing':
        """
        从字典创建实例
        Create instance from dictionary
        """
        # 处理datetime字段
        if 'created_at' in data and isinstance(data['created_at'], str):
            try:
                data['created_at'] = datetime.fromisoformat(data['created_at'])
            except ValueError:
                data['created_at'] = datetime.now()
        
        return cls(**data)
    
    @classmethod
    def from_json(cls, json_str: str) -> 'PropertyListing':
        """
        从JSON字符串创建实例
        Create instance from JSON string
        """
        data = json.loads(json_str)
        return cls.from_dict(data)
    
    def get_unique_id(self) -> str:
        """
        获取基于detail_url的唯一标识
        Get unique identifier based on detail_url
        """
        # 从detail_url提取唯一标识
        import hashlib
        return hashlib.md5(self.detail_url.encode('utf-8')).hexdigest()
    
    def is_valid_data_quality(self) -> bool:
        """
        检查数据质量是否符合要求
        Check if data quality meets requirements
        """
        # 检查关键字段是否有实际内容
        if len(self.title.strip()) < 5:
            return False
        
        if not self.rent_range or '面议' in self.rent_range:
            return False
        
        if not self.area_range or '面议' in self.area_range:
            return False
        
        return True
    
    def __str__(self) -> str:
        """字符串表示"""
        return f"PropertyListing(id={self.id}, title={self.title[:30]}..., city={self.city})"
    
    def __repr__(self) -> str:
        """详细字符串表示"""
        return (f"PropertyListing(id='{self.id}', title='{self.title}', "
                f"city='{self.city}', business_type='{self.business_type}')")